<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from "vue";
import { ElMessage } from "element-plus";
import dayjs from "dayjs";
import * as echarts from "echarts";
import { generateLifeDescription } from "./services/api";
import Instructions from "./components/Instructions.vue";
import { exportLifeStatsAsImage } from "./utils/exportUtils";
import { CopyDocument } from "@element-plus/icons-vue";
import { useDark, useToggle, usePreferredDark } from "@vueuse/core";
import { VERSION } from "./version.js";
import { 
  AiFillGithub,
  AiFillAppstore,
  AiOutlineLaptop,
  AiOutlineFork,
  AiOutlineExclamationCircle,
  AiFillTikTok,
  AiFillZhihuCircle
 } from 'vue-icons-plus/ai'
 import { VscCircleLargeFilled } from 'vue-icons-plus/vsc'
 import { 
  DiNodejs,
  DiNpm,
  DiGit,
  DiGitBranch,
  DiJavascript1,
  DiMarkdown
} from 'vue-icons-plus/di'

// 复制描述内容的方法
const copyDescription = () => {
  if (!description.value) return;

  navigator.clipboard
    .writeText(description.value)
    .then(() => {
      ElMessage.success({
        message: "内容已复制到剪贴板",
        duration: 2000,
      });
    })
    .catch((err) => {
      console.error("复制失败:", err);
      ElMessage.error("复制失败，请手动选择文本复制");
    });
};
// 夜间模式相关代码
const isDark = useDark();
const toggleDark = useToggle(isDark);
// 添加系统主题检测
const prefersDark = usePreferredDark();
// 是否跟随系统
const followSystem = ref(false);
// 添加应用版本号
const appVersion = ref(VERSION);

// 监听系统主题变化
watch(prefersDark, (newValue) => {
  if (followSystem.value) {
    // 如果设置为跟随系统，则根据系统主题更新应用主题
    isDark.value = newValue;
  }
});

// 切换跟随系统模式
function toggleFollowSystem() {
  followSystem.value = !followSystem.value;

  if (followSystem.value) {
    // 立即应用系统主题
    isDark.value = prefersDark.value;
    ElMessage.success("已切换为跟随系统主题模式");
  } else {
    ElMessage.info("已切换为手动主题模式");
  }

  // 将设置保存到本地存储
  localStorage.setItem("followSystemTheme", followSystem.value);
}

// 侧边栏状态
const isCollapse = ref(true);
const isMobile = ref(window.innerWidth <= 768);
const isReceivingStream = ref(false); // 新增：标记是否正在接收流式内容

const handleCollapse = () => {
  isCollapse.value = !isCollapse.value;
};

// 监听窗口大小变化
onMounted(() => {
  window.addEventListener("resize", () => {
    isMobile.value = window.innerWidth <= 768;
    if (!isMobile.value && isCollapse.value === false) {
      isCollapse.value = true;
    }
  });
});

// 用户输入数据
const birthDate = ref("");
const lifeExpectancy = ref(80);

// 励志名言
const quotes = [
  { text: "人生如棋，落子无悔", author: "佚名" },
  { text: "不要等待机会，而要创造机会", author: "林肯" },
  { text: "生命不在于长短，而在于如何活出精彩", author: "蒙田" },
];
const currentQuote = ref(quotes[Math.floor(Math.random() * quotes.length)]);
// 当前选中的格子信息
const selectedCell = ref(null);
const description = ref("");
const loading = ref(false);
// 统计数据
const lifeStats = computed(() => {
  if (!birthDate.value) return null;
  const birthMoment = dayjs(birthDate.value);
  const now = dayjs();
  // 精确计算已经度过的天数（包括月份和天数）
  const livedDays = now.diff(birthMoment, "day");
  const totalDays = lifeExpectancy.value * 365;
  const remainingDays = totalDays - livedDays;
  const percentageLived = ((livedDays / totalDays) * 100).toFixed(2);
  // 计算各生命阶段的时长占比
  const stageStats = [
    { name: "婴儿期", value: Math.min(3, lifeExpectancy.value) },
    {
      name: "幼儿期",
      value: Math.min(3, Math.max(0, lifeExpectancy.value - 3)),
    },
    {
      name: "童年期",
      value: Math.min(6, Math.max(0, lifeExpectancy.value - 6)),
    },
    {
      name: "青少年期",
      value: Math.min(6, Math.max(0, lifeExpectancy.value - 12)),
    },
    {
      name: "成年早期",
      value: Math.min(7, Math.max(0, lifeExpectancy.value - 18)),
    },
    {
      name: "青年期",
      value: Math.min(10, Math.max(0, lifeExpectancy.value - 25)),
    },
    {
      name: "中年早期",
      value: Math.min(10, Math.max(0, lifeExpectancy.value - 35)),
    },
    {
      name: "中年期",
      value: Math.min(15, Math.max(0, lifeExpectancy.value - 45)),
    },
    { name: "老年期", value: Math.max(0, lifeExpectancy.value - 60) },
  ];
  return {
    totalDays,
    livedDays,
    remainingDays,
    percentageLived,
    stageStats,
  };
});
// 更精确的年龄计算，保留一位小数
const userAge = computed(() => {
  if (!birthDate.value) return 0;
  const years = dayjs().diff(dayjs(birthDate.value), "year", true);
  return Math.floor(years); // 如果想保留小数可以使用 years.toFixed(1) 代替
});
//显示已经活了多长时间，精确到秒，还剩余多长时间，也精确到秒
// 添加一个用于触发秒级更新的变量
const currentTime = ref(Date.now());
//显示已经活了多长时间，精确到秒，还剩余多长时间，也精确到秒
const lifeTimeDetails = computed(() => {
  if (!birthDate.value) return null;
  // 让计算属性依赖currentTime，确保每秒更新
  const currentMs = currentTime.value % 1000; // 获取当前毫秒数
  const birthMoment = dayjs(birthDate.value);
  const now = dayjs();
  const endOfLife = birthMoment.add(lifeExpectancy.value, "year");
  // 计算已生活和剩余时间的各个单位
  const lived = {
    years: now.diff(birthMoment, "year"),
    months: now.diff(birthMoment, "month") % 12,
    days: now.diff(birthMoment, "day") % 30,
    hours: now.diff(birthMoment, "hour") % 24,
    minutes: now.diff(birthMoment, "minute") % 60,
    seconds: now.diff(birthMoment, "second") % 60,
    milliseconds: currentMs, // 添加毫秒
  };
  const remaining = {
    years: endOfLife.diff(now, "year"),
    months: endOfLife.diff(now, "month") % 12,
    days: endOfLife.diff(now, "day") % 30,
    hours: endOfLife.diff(now, "hour") % 24,
    minutes: endOfLife.diff(now, "minute") % 60,
    seconds: endOfLife.diff(now, "second") % 60,
    milliseconds: 999 - currentMs, // 添加毫秒
  };
  // 总秒数计算
  const totalLivedSeconds = now.diff(birthMoment, "second");
  const totalRemainingSeconds = endOfLife.diff(now, "second");
  return {
    lived,
    remaining,
    totalLivedSeconds,
    totalRemainingSeconds,
  };
});
// 优化定时器函数
let secondsTimer = null;
// 在onMounted中设置定时器
onMounted(() => {
  // 其他onMounted代码保持不变...
  // 使用RequestAnimationFrame获得更流畅的毫秒更新
  let frameId = null;
  const updateTime = () => {
    currentTime.value = Date.now();
    frameId = requestAnimationFrame(updateTime);
  };
  // 启动动画帧更新
  frameId = requestAnimationFrame(updateTime);
  // 添加秒级更新定时器
  secondsTimer = setInterval(() => {
    // 强制重新计算，更新响应式变量
    currentTime.value = Date.now();
  }, 1000);
});
// 在组件卸载时清除定时器
onUnmounted(() => {
  if (secondsTimer) {
    clearInterval(secondsTimer);
  }
  document.removeEventListener("fullscreenchange", () => { });
});
// 重要时间节点
const milestones = computed(() => {
  if (!birthDate.value) return [];
  const birthYear = dayjs(birthDate.value).year();
  return [
    { age: 18, year: birthYear + 18, description: "成年" },
    { age: 22, year: birthYear + 22, description: "大学毕业" },
    { age: 30, year: birthYear + 30, description: "而立之年" },
    { age: 40, year: birthYear + 40, description: "不惑之年" },
    { age: 50, year: birthYear + 50, description: "知天命之年" },
    { age: 60, year: birthYear + 60, description: "花甲之年" },
    { age: 70, year: birthYear + 70, description: "古稀之年" },
  ].filter((milestone) => milestone.age > userAge.value);
});
// 生成生命格子数据
const lifeGrid = computed(() => {
  const grid = [];
  // 即使未输入出生日期也显示默认的生命格子
  const currentAge = birthDate.value ? userAge.value : null;
  for (let i = 1; i <= lifeExpectancy.value; i++) {
    const isPast = currentAge !== null && i <= currentAge;
    const isCurrent = currentAge !== null && i === currentAge;
    grid.push({
      age: i,
      isPast,
      isCurrent,
      stage: getLifeStage(i),
    });
  }
  return grid;
});
// 获取人生阶段
function getLifeStage(age) {
  if (age < 3) return "婴儿期";
  if (age < 6) return "幼儿期";
  if (age < 12) return "童年期";
  if (age < 18) return "青少年期";
  if (age < 25) return "成年早期";
  if (age < 35) return "青年期";
  if (age < 45) return "中年早期";
  if (age < 60) return "中年期";
  return "老年期";
}
// 选择格子，获取描述
// 在已有变量声明附近添加
const reasoningContent = ref(""); // 新增：存储思维链内容
const showReasoning = ref(true); // 新增：控制思维链显示/隐藏
// 修改selectCell函数处理思维链内容
async function selectCell(cell) {
  // 检查是否已填写出生日期
  if (!birthDate.value) {
    ElMessage.warning(
      "请先填写您的出生日期，以便我们为您生成更准确的人生阶段描述"
    );
    return;
  }
  selectedCell.value = cell;
  loading.value = true;
  isReceivingStream.value = false; // 标记开始接收流式内容
  description.value = ""; // 重置内容，确保从空开始
  reasoningContent.value = ""; // 重置思维链内容
  showReasoning.value = true; // 默认显示思维链
  // 添加加载动画效果
  const loadingChars = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
  let loadingIndex = 0;
  const loadingAnimation = setInterval(() => {
    const loadingChar = loadingChars[loadingIndex];
    description.value = `Deepseek R1正在响应${loadingChar}`;
    loadingIndex = (loadingIndex + 1) % loadingChars.length;
  }, 100);
  ElMessage.info("正在请求Deepseek R1的理解");
  try {
    // 提供流式更新回调
    await generateLifeDescription(
      {
        age: cell.age,
        stage: cell.stage,
        birthYear: dayjs(birthDate.value).year(),
        lifeExpectancy: lifeExpectancy.value,
      },
      // 在selectCell函数中，修改回调函数：
      (newContent, isFirst, newReasoningContent) => {
        // 清除加载动画
        if (isFirst) {
          clearInterval(loadingAnimation);
          loading.value = false;
          isReceivingStream.value = true;
        }
        // 收到有效内容后才更新
        if (newContent && newContent.trim()) {
          description.value = newContent;
        }
        // 添加详细调试日志，显示思维链内容更新
        if (newReasoningContent && newReasoningContent.trim()) {
          console.log(`更新思维链内容，长度: ${newReasoningContent.length}`);
          console.log(
            `新增内容: "${newReasoningContent.substring(
              Math.max(0, newReasoningContent.length - 50)
            )}"...`
          );
          reasoningContent.value = newReasoningContent;
          // 如果有思维链内容但没显示按钮，检查DOM
          if (newReasoningContent.length > 0) {
            console.log(
              "已接收思维链内容，按钮显示状态:",
              !!document.querySelector(".show-reasoning-btn")
            );
          }
        }
      }
    );
    ElMessage.success("阶段人生理解来自于Deepseek R1");
  } catch (error) {
    console.error("获取描述失败:", error);
    ElMessage.error("获取描述失败，请稍后重试");
    // 出错时清空描述，避免显示加载动画
    description.value = "获取描述失败，请稍后重试";
  } finally {
    // 确保清理加载动画
    clearInterval(loadingAnimation);
    loading.value = false;
    isReceivingStream.value = false; // 无论成功失败，都确保关闭流式状态
  }
}
// 更换励志名言
function changeQuote() {
  const newQuote = quotes[Math.floor(Math.random() * quotes.length)];
  // 确保不会连续出现相同的名言
  if (newQuote.text === currentQuote.value.text) {
    changeQuote();
    return;
  }
  currentQuote.value = newQuote;
}
// 图表相关
let myChart = null;
const stageChart = ref(null);
// 监听数据变化，初始化或更新图表
watch(
  () => lifeStats.value?.stageStats,
  (newStats) => {
    if (newStats) {
      const chartDom = stageChart.value;
      if (chartDom) {
        if (!myChart) {
          myChart = echarts.init(chartDom);
          // 监听窗口大小变化，调整图表大小
          window.addEventListener("resize", () => {
            myChart.resize();
          });
        }
        const option = {
          tooltip: {
            trigger: "item",
            formatter: "{b}: {c}年 ({d}%)",
          },
          series: [
            {
              name: "生命阶段",
              type: "pie",
              radius: ["40%", "70%"],
              avoidLabelOverlap: false,
              itemStyle: {
                borderRadius: 10,
                borderColor: "#fff",
                borderWidth: 2,
              },
              label: {
                show: true,
                position: "outside",
                formatter: "{b}\n{c}年",
              },
              emphasis: {
                label: {
                  show: true,
                  fontSize: 20,
                  fontWeight: "bold",
                },
              },
              data: newStats.map((stage) => ({
                name: stage.name,
                value: stage.value,
              })),
            },
          ],
        };
        myChart.setOption(option);
      }
    }
  },
  { deep: true }
);
// 全屏模式相关代码
const isFullscreen = ref(false);
// 切换全屏方法
function toggleFullScreen() {
  if (!document.fullscreenElement) {
    // 进入全屏
    document.documentElement
      .requestFullscreen()
      .then(() => {
        isFullscreen.value = true;
        ElMessage.success("已进入全屏模式");
      })
      .catch((err) => {
        console.error(`无法进入全屏模式: ${err.message}`);
        ElMessage.error("无法进入全屏模式");
      });
  } else {
    // 退出全屏
    if (document.exitFullscreen) {
      document
        .exitFullscreen()
        .then(() => {
          isFullscreen.value = false;
          ElMessage.info("已退出全屏模式");
        })
        .catch((err) => {
          console.error(`退出全屏出错: ${err.message}`);
        });
    }
  }
}
onMounted(() => {
  const savedFollowSystem = localStorage.getItem("followSystemTheme");
  if (savedFollowSystem !== null) {
    followSystem.value = savedFollowSystem === "true";

    // 如果设置为跟随系统，立即应用系统主题
    if (followSystem.value) {
      isDark.value = prefersDark.value;
    }
  }
  // 监听isDark变化，更新HTML元素的class
  watch(
    isDark,
    (newVal) => {
      if (newVal) {
        document.documentElement.classList.add("dark");
      } else {
        document.documentElement.classList.remove("dark");
      }
    },
    { immediate: true }
  );
  // 监听全屏状态变化
  document.addEventListener("fullscreenchange", () => {
    isFullscreen.value = !!document.fullscreenElement;
  });
  setInterval(() => {
    changeQuote();
  }, 30000); // 每30秒更换一次
  // 阻止双击缩放
  document.addEventListener(
    "touchstart",
    function (event) {
      if (event.touches.length > 1) {
        event.preventDefault();
      }
    },
    { passive: false }
  );
  let lastTouchEnd = 0;
  document.addEventListener(
    "touchend",
    function (event) {
      const now = Date.now();
      if (now - lastTouchEnd < 300) {
        event.preventDefault();
      }
      lastTouchEnd = now;
    },
    { passive: false }
  );
  // 阻止多点触控手势
  document.addEventListener(
    "gesturestart",
    function (event) {
      event.preventDefault();
    },
    { passive: false }
  );
  document.addEventListener(
    "gesturechange",
    function (event) {
      event.preventDefault();
    },
    { passive: false }
  );
  // 防止输入框焦点导致的缩放
  preventDatePickerZoom();
});
// 在Vue组件内部添加一个特定方法来处理日期选择
function handleDatePickerFocus(event) {
  // 防止默认行为可能导致的缩放
  document.documentElement.style.fontSize = "100%";
  // 在iOS上，可以尝试滚动到视图中央，分散用户注意力，减少缩放场景
  if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
    setTimeout(() => {
      const scrollY = window.scrollY;
      window.scrollTo(0, scrollY + 1);
      window.scrollTo(0, scrollY);
    }, 100);
  }
}
// 然后修改您的el-date-picker组件，添加事件处理：
// 添加一个新函数来防止日期选择器缩放
function preventDatePickerZoom() {
  // 使用setTimeout确保元素已经渲染
  setTimeout(() => {
    const dateInputs = document.querySelectorAll(".el-date-editor input");
    dateInputs.forEach((input) => {
      // 设置大字体，防止iOS自动缩放
      input.style.fontSize = "16px";

      // 阻止焦点事件默认行为
      input.addEventListener("focus", (e) => {
        // 可以在这里添加特定处理
        document.body.classList.add("input-focus");
      });

      input.addEventListener("blur", (e) => {
        document.body.classList.remove("input-focus");
      });
    });
  }, 500); // 延迟500ms确保元素已加载
}
// 动态更新的生命百分比，保留高精度
const dynamicPercentage = computed(() => {
  if (!birthDate.value || !lifeStats.value) return "0.000000";
  // 让计算依赖currentTime以实现动态更新
  const _ = currentTime.value;
  const birthMoment = dayjs(birthDate.value);
  const now = dayjs();
  // 计算精确到秒的百分比
  const totalSeconds = lifeExpectancy.value * 365 * 24 * 60 * 60;
  const livedSeconds = now.diff(birthMoment, "second");
  // 保留6位小数
  return ((livedSeconds / totalSeconds) * 100).toFixed(6);
});
// 格式化函数，确保显示6位小数
function percentFormat(percentage) {
  return `${percentage.toFixed(6)}%`;
}
// 添加视图控制变量和方法
const currentView = ref("main");
function showInstructions() {
  currentView.value = "instructions";
}
function showMainView() {
  currentView.value = "main";
}
// 导出相关变量
const exportDialogVisible = ref(false);
const exportUsername = ref("");
// 添加导出函数
// 显示导出对话框
function exportLifeStats() {
  if (!birthDate.value) {
    ElMessage.warning("请先填写您的出生日期，才能导出统计图片");
    return;
  }
  exportDialogVisible.value = true;
  exportUsername.value = ""; // 重置输入框
}
// 确认导出
function confirmExport() {
  exportDialogVisible.value = false;
  try {
    // 准备要导出的数据，包括用户名
    const exportData = {
      userAge: userAge.value,
      birthDate: birthDate.value,
      lifeExpectancy: lifeExpectancy.value,
      lifeStats: lifeStats.value,
      lifeTimeDetails: lifeTimeDetails.value,
      dynamicPercentage: dynamicPercentage.value,
      isDark: isDark.value,
      userName: exportUsername.value.trim() || "亲爱的你",
    };
    // 调用导出功能
    exportLifeStatsAsImage(exportData);
  } catch (error) {
    console.error("导出失败:", error);
    ElMessage.error("导出失败，请在电脑上尝试此功能");
  }
}
// 添加刷新页面和切换侧边栏的方法
function refreshPage() {
  window.location.reload();
}
function toggleSidebar() {
  if (isMobile.value) {
    isCollapse.value = !isCollapse.value;
  }
}
// 加载状态控制
const isLoading = ref(true);
const loadingDots = ref("");
// 在onMounted中添加
onMounted(() => {
  // 其他onMounted代码保持不变
  // 加载动画的点
  let dotsCount = 0;
  const dotsInterval = setInterval(() => {
    dotsCount = (dotsCount + 1) % 4;
    loadingDots.value = ".".repeat(dotsCount);
  }, 500);
  // 延迟关闭加载页面
  setTimeout(() => {
    clearInterval(dotsInterval);
    isLoading.value = false;
  }, 2000); // 可以根据需要调整时间
  // 刷新页面时重置加载状态
  window.addEventListener("beforeunload", () => {
    isLoading.value = true;
  });
});
</script>

<template>
  <div class="app-container">
    <!-- 添加加载层 -->
    <transition name="fade">
      <div v-if="isLoading" class="loading-screen">
        <div class="loading-content">
          <div class="loading-spinner">
            <img src="/web-app-manifest-512x512.png" alt="LOGO" class="loding-logo">
          </div>
          <h2 class="loading-title">人生计算器</h2>
          <p class="loading-subtitle">正在加载界面{{ loadingDots }}</p>
        </div>
      </div>
    </transition>
    <!-- 侧边栏 -->
    <el-menu class="sidebar" :collapse="isCollapse" :collapse-transition="false" :class="{ collapsed: isCollapse }">
      <div class="sidebar-header">
        <el-button class="collapse-btn" :icon="isCollapse ? 'Expand' : 'Fold'" @click="handleCollapse" circle />
      </div>
      <el-menu-item index="1" @click="showMainView">
        <el-icon>
          <House />
        </el-icon>
        <template #title>主页</template>
      </el-menu-item>
      <el-menu-item index="2" @click="showInstructions">
        <el-icon>
          <Opportunity />
        </el-icon>
        <template #title>说明</template>
      </el-menu-item>
      <!-- 版本号显示 -->
      <div class="version-container">
        <el-icon>
          <InfoFilled />
        </el-icon>
        <span v-show="!isCollapse" class="version-text">{{ appVersion }}</span>
      </div>
    </el-menu>
    <template>
      <div class="app-container">
        <el-dialog v-model="exportDialogVisible" title="导出图片" width="400px" center append-to-body :modal="true"
          :close-on-click-modal="false" :close-on-press-escape="true" :z-index="2000" class="export-dialog">
          <div class="export-dialog-content">
            <p>输入名字，我们将为您在图片下方水印处创建专属祝福</p>
            <el-input v-model="exportUsername" placeholder="可以输入您的名字或者直接导出" maxlength="10" show-word-limit></el-input>
          </div>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="exportDialogVisible = false">取消</el-button>
              <el-button type="primary" @click="confirmExport">
                导出
              </el-button>
            </div>
          </template>
        </el-dialog>
      </div>
    </template>
    <div class="main-wrapper" :class="{ expanded: isCollapse }">
      <div v-if="currentView === 'main'">
        <!-- 修改header的动态样式，添加isMobile条件 -->
        <div class="header" :style="{ left: isMobile ? '0' : isCollapse ? '64px' : '98px' }">
          <div class="header-content" :class="{ 'mobile-header': isMobile }">
            <h2 class="title-container">
              <!-- 点击文字刷新页面 -->
              <span class="title-text" @click="refreshPage" :class="{ 'clickable-title': true }">
                  <!--加上logo并添加class-->
                  <img src="/favicon.svg" alt="LOGO" class="header-logo">
                  人生计算器
              </span>
              <!-- 点击图标打开侧边栏 -->
              <div v-if="isMobile" @click="toggleSidebar" class="icon-wrapper">
                <el-icon class="title-icon" style="font-size: 24px">
                  <Operation />
                </el-icon>
              </div>
            </h2>
            <div class="notice-container" v-if="!isMobile">
              <el-tag size="small" type="info">温馨提示</el-tag>
              <span class="notice-content">本应用仅供娱乐参考！</span>
            </div>
            <div v-if="isMobile" class="mobile-theme-toggle">
              <!-- 系统主题按钮 -->
              <el-tooltip :content="followSystem ? '已跟随系统主题' : '点击跟随系统主题'" placement="bottom" :hide-after="1500"
                effect="light">
                <el-button :icon="followSystem ? 'Cellphone' : 'Sunrise'" @click="toggleFollowSystem" circle
                  size="default" :type="followSystem ? 'success' : ''" class="system-theme-btn" />
              </el-tooltip>
              <!-- 深色主题按钮 -->
              <el-tooltip :content="followSystem
                ? '已启用跟随系统主题，无法手动切换'
                : isDark
                  ? '切换为浅色模式'
                  : '切换为深色模式'
                " placement="bottom" :hide-after="1500" effect="light">
                <el-button :icon="isDark ? 'Sunny' : 'Moon'" :type="isDark ? 'warning' : 'info'" @click="toggleDark()"
                  circle size="default" class="theme-toggle-btn" :disabled="followSystem" />
              </el-tooltip>
            </div>
          </div>
          <div class="quote-container" v-if="!isMobile">
            <span class="quote">"{{ currentQuote.text }}"</span>
            <span class="quote-author">—— {{ currentQuote.author }}</span>
            <div class="header-actions">
              <!-- 系统主题按钮 -->
              <el-tooltip :content="followSystem ? '已跟随系统主题' : '点击跟随系统主题'" placement="bottom">
                <el-button :icon="followSystem ? 'Monitor' : 'Sunrise'" @click="toggleFollowSystem" circle size="default"
                  :type="followSystem ? 'success' : ''" class="system-theme-btn" />
              </el-tooltip>
              <el-tooltip :content="followSystem
                ? '已启用跟随系统主题，无法手动切换'
                : isDark
                  ? '切换为浅色模式'
                  : '切换为深色模式'
                " placement="bottom">
                <el-button :icon="isDark ? 'Sunny' : 'Moon'" @click="toggleDark()" circle size="default"
                  :type="isDark ? 'warning' : 'info'" class="theme-toggle-btn" :disabled="followSystem" />
              </el-tooltip>
              <el-tooltip :content="isFullscreen ? '退出全屏' : '打开全屏'" placement="bottom">
                <el-button :icon="isFullscreen ? 'Close' : 'FullScreen'" @click="toggleFullScreen" circle size="default"
                  :class="['fullscreen-btn', { 'is-active': isFullscreen }]" />
              </el-tooltip>
            </div>
          </div>
        </div>
        <div class="main-content">
          <!-- 用户输入区域 -->
          <div class="input-section">
            <el-card class="input-card" shadow="hover">
              <template #header>
                <div class="card-header">
                  <span>基本信息</span>
                </div>
              </template>
              <el-form :inline="true">
                <el-form-item label="出生日期">
                  <el-date-picker :editable="false" v-model="birthDate" type="date" placeholder="选择出生日期"
                    :disabled-date="(date) => date > new Date()" @focus="handleDatePickerFocus" />
                </el-form-item>
                <el-form-item label="预期寿命">
                  <el-input-number v-model="lifeExpectancy" :min="1" :max="120" />
                </el-form-item>
              </el-form>
            </el-card>
            <!-- 添加导出按钮 -->
            <el-button size="large" type="primary" icon="Upload" class="export-btn" @click="exportLifeStats">
              导出图片
            </el-button>
            <div v-if="!birthDate" class="empty-state">
              <el-empty description="请先选择您的出生日期，以查看详细的探索世界进度统计数据">
                <el-button type="primary" @click="$el.querySelector('.el-date-editor input').focus()">
                  选择您的出生日期
                </el-button>
              </el-empty>
            </div>
            <!-- 在生命统计卡片内部，放在stats-container下方，chart-container上方 -->
            <div v-if="lifeStats" class="stats-container">
              <div class="stat-item primary">
                <el-icon>
                  <Calendar />
                </el-icon>
                <div class="stat-value">{{ userAge }}</div>
                <div class="stat-label">您当前年龄</div>
              </div>
              <div class="stat-item success">
                <el-icon>
                  <Timer />
                </el-icon>
                <div class="stat-value">{{ lifeStats.percentageLived }}%</div>
                <div class="stat-label">已探索世界市场</div>
              </div>
              <div class="stat-item warning">
                <el-icon>
                  <Clock />
                </el-icon>
                <div class="stat-value">{{ lifeExpectancy - userAge }}</div>
                <div class="stat-label">剩余探索时长</div>
              </div>
              <div class="stat-item info">
                <el-icon>
                  <Sunrise />
                </el-icon>
                <div class="stat-value">
                  {{ lifeStats.remainingDays.toLocaleString() }}
                </div>
                <div class="stat-label">剩余探索天数</div>
              </div>
            </div>
            <!-- 添加精确到秒的时间详情 -->
            <div v-if="lifeTimeDetails" class="time-details-section">
              <div class="time-details-title">精确统计</div>
              <div class="time-details-container">
                <div class="time-details-column">
                  <div class="time-details-header">探索已花费了</div>
                  <div class="time-details-content">
                    <div class="time-details-row">
                      <span class="time-unit">{{
                        lifeTimeDetails.lived.years
                      }}</span>
                      年
                      <span class="time-unit">{{
                        lifeTimeDetails.lived.months
                      }}</span>
                      月
                      <span class="time-unit">{{
                        lifeTimeDetails.lived.days
                      }}</span>
                      天
                    </div>
                    <div class="time-details-row">
                      <span class="time-unit">{{
                        lifeTimeDetails.lived.hours
                      }}</span>
                      时
                      <span class="time-unit">{{
                        lifeTimeDetails.lived.minutes
                      }}</span>
                      分
                      <span class="time-unit">{{
                        lifeTimeDetails.lived.seconds
                      }}</span>
                      秒
                      <span class="time-unit millisecond">{{
                        lifeTimeDetails.lived.milliseconds
                          .toString()
                          .padStart(3, "0")
                      }}</span>
                      毫秒
                    </div>
                    <div class="time-details-total">
                      总计:
                      {{ lifeTimeDetails.totalLivedSeconds.toLocaleString() }}
                      秒
                    </div>
                  </div>
                </div>
                <div class="time-details-column">
                  <div class="time-details-header">剩余探索时长</div>
                  <div class="time-details-content">
                    <div class="time-details-row">
                      <span class="time-unit">{{
                        lifeTimeDetails.remaining.years
                      }}</span>
                      年
                      <span class="time-unit">{{
                        lifeTimeDetails.remaining.months
                      }}</span>
                      月
                      <span class="time-unit">{{
                        lifeTimeDetails.remaining.days
                      }}</span>
                      天
                    </div>
                    <div class="time-details-row">
                      <span class="time-unit">{{
                        lifeTimeDetails.remaining.hours
                      }}</span>
                      时
                      <span class="time-unit">{{
                        lifeTimeDetails.remaining.minutes
                      }}</span>
                      分
                      <span class="time-unit">{{
                        lifeTimeDetails.remaining.seconds
                      }}</span>
                      秒
                      <span class="time-unit millisecond">{{
                        lifeTimeDetails.remaining.milliseconds
                          .toString()
                          .padStart(3, "0")
                      }}</span>
                      毫秒
                    </div>
                    <div class="time-details-total">
                      总计:
                      {{
                        lifeTimeDetails.totalRemainingSeconds.toLocaleString()
                      }}
                      秒
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <!-- 生命阶段分布图表 -->
            <div class="chart-container" v-if="
              lifeStats &&
              lifeStats.stageStats &&
              lifeStats.stageStats.length > 0
            ">
              <div class="chart-title">人生阶段分布</div>
              <div class="stage-chart" ref="stageChart"></div>
              <div class="chart-title">人生进度</div>
              <el-progress :percentage="parseFloat(dynamicPercentage)" status="success" :text-inside="true"
                :stroke-width="20" :format="percentFormat" />
            </div>
            <!-- 重要时间节点 -->
            <el-card v-if="birthDate && milestones.length > 0" class="milestones-card" shadow="hover">
              <template #header>
                <div class="card-header">
                  <span>人生里程碑</span>
                </div>
              </template>
              <el-timeline>
                <el-timeline-item v-for="(milestone, index) in milestones.slice(0, 3)" :key="index"
                  :timestamp="milestone.year + '年'" :type="index === 0 ? 'primary' : ''">
                  {{ milestone.age }}岁 - {{ milestone.description }}
                </el-timeline-item>
              </el-timeline>
            </el-card>
          </div>
          <!-- 生命格子展示区域 -->
          <div class="life-grid-container">
            <!-- 替换描述展示区域 -->
            <el-card v-if="selectedCell" class="description-card" shadow="hover" v-loading="loading">
              <template #header>
                <div class="card-header">
                  <div class="card-header-left">
                    <span>{{ selectedCell.age }}岁 - {{ selectedCell.stage }}</span>
                    <span v-if="loading && !isReceivingStream" class="streaming-status">R1响应中...</span>
                    <span v-else-if="isReceivingStream" class="streaming-status">请稍等...</span>
                  </div>
                  <el-button size="small" class="show-reasoning-btn" @click="showReasoning = !showReasoning"
                    :disabled="!reasoningContent" :type="showReasoning ? 'primary' : 'default'">
                    {{ showReasoning ? "隐藏思维链" : "显示思维链" }}
                    <span v-if="reasoningContent">
                      ({{ reasoningContent.length }}字)</span>
                  </el-button>
                </div>
              </template>
              <!-- 默认显示思维链内容 -->
              <transition name="reasoning">
                <div v-if="reasoningContent && showReasoning" class="reasoning-content">
                  <div class="reasoning-header">
                    <el-divider content-position="left" class="reasoning-divider">思维链过程</el-divider>
                  </div>
                  <pre>{{ reasoningContent }}</pre>
                </div>
              </transition>
              <div class="description-content">
                <p>
                  {{ description || "等待Deepseek R1响应" }}
                  <span v-if="loading || isReceivingStream" class="loading-indicator"><VscCircleLargeFilled />
                  </span>
                </p>
              </div>
              <div class="description-header">
                <el-button v-if="description && !isReceivingStream" size="small" :icon="CopyDocument" circle
                  @click="copyDescription" class="copy-btn" title="复制内容"></el-button>
              </div>
            </el-card>
            <el-card class="life-grid-card" shadow="hover">
              <template #header>
                <div class="card-header">
                  <span>人生时间线</span>
                  <span style="color: #7b7b7b">点击格子查看Deepseek人生理解</span>
                </div>
              </template>
              <div class="life-grid">
                <div v-for="cell in lifeGrid" :key="cell.age" class="life-cell" :class="{
                  past: cell.isPast,
                  current: cell.isCurrent,
                  selected: selectedCell?.age === cell.age,
                  milestone:
                    milestones && milestones.some((m) => m.age === cell.age),
                }" @click="selectCell(cell)">
                  <el-popover v-if="selectedCell?.age === cell.age && description" placement="top" :width="300"
                    trigger="hover" :content="description" popper-class="description-popover">
                    <template #reference>
                      <div>
                        <span class="age">{{ cell.age }}</span>
                        <span class="stage">{{ cell.stage }}</span>
                        <span style="left: 10px; width: 10px; height: 10px">
                          <svg viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg" width="25" height="25"
                            xmlns:xlink="http://www.w3.org/1999/xlink">
                            <path id="path"
                              d="M27.501 8.46875C27.249 8.3457 27.1406 8.58008 26.9932 8.69922C26.9434 8.73828 26.9004 8.78906 26.8584 8.83398C26.4902 9.22852 26.0605 9.48633 25.5 9.45508C24.6787 9.41016 23.9785 9.66797 23.3594 10.2969C23.2275 9.52148 22.79 9.05859 22.125 8.76172C21.7764 8.60742 21.4238 8.45312 21.1807 8.11719C21.0098 7.87891 20.9639 7.61328 20.8779 7.35156C20.8242 7.19336 20.7695 7.03125 20.5879 7.00391C20.3906 6.97266 20.3135 7.13867 20.2363 7.27734C19.9258 7.84375 19.8066 8.46875 19.8174 9.10156C19.8447 10.5234 20.4453 11.6562 21.6367 12.4629C21.7725 12.5547 21.8076 12.6484 21.7646 12.7832C21.6836 13.0605 21.5869 13.3301 21.501 13.6074C21.4473 13.7852 21.3662 13.8242 21.1768 13.7461C20.5225 13.4727 19.957 13.0684 19.458 12.5781C18.6104 11.7578 17.8438 10.8516 16.8877 10.1426C16.6631 9.97656 16.4395 9.82227 16.207 9.67578C15.2314 8.72656 16.335 7.94727 16.5898 7.85547C16.8574 7.75977 16.6826 7.42773 15.8193 7.43164C14.957 7.43555 14.167 7.72461 13.1611 8.10938C13.0137 8.16797 12.8594 8.21094 12.7002 8.24414C11.7871 8.07227 10.8389 8.0332 9.84766 8.14453C7.98242 8.35352 6.49219 9.23633 5.39648 10.7441C4.08105 12.5547 3.77148 14.6133 4.15039 16.7617C4.54883 19.0234 5.70215 20.8984 7.47559 22.3633C9.31348 23.8809 11.4307 24.625 13.8457 24.4824C15.3125 24.3984 16.9463 24.2012 18.7881 22.6406C19.2529 22.8711 19.7402 22.9629 20.5498 23.0332C21.1729 23.0918 21.7725 23.002 22.2373 22.9062C22.9648 22.752 22.9141 22.0781 22.6514 21.9531C20.5186 20.959 20.9863 21.3633 20.5605 21.0371C21.6445 19.752 23.2783 18.418 23.917 14.0977C23.9668 13.7539 23.9238 13.5391 23.917 13.2598C23.9131 13.0918 23.9512 13.0254 24.1445 13.0059C24.6787 12.9453 25.1973 12.7988 25.6738 12.5352C27.0557 11.7793 27.6123 10.5391 27.7441 9.05078C27.7637 8.82422 27.7402 8.58789 27.501 8.46875ZM15.46 21.8613C13.3926 20.2344 12.3906 19.6992 11.9766 19.7227C11.5898 19.7441 11.6592 20.1875 11.7441 20.4766C11.833 20.7617 11.9492 20.959 12.1123 21.209C12.2246 21.375 12.3018 21.623 12 21.8066C11.334 22.2207 10.1768 21.668 10.1221 21.6406C8.77539 20.8477 7.64941 19.7988 6.85547 18.3652C6.08984 16.9844 5.64453 15.5039 5.57129 13.9238C5.55176 13.541 5.66406 13.4062 6.04297 13.3379C6.54199 13.2461 7.05762 13.2266 7.55664 13.2988C9.66602 13.6074 11.4619 14.5527 12.9668 16.0469C13.8262 16.9004 14.4766 17.918 15.1465 18.9121C15.8584 19.9688 16.625 20.9746 17.6006 21.7988C17.9443 22.0879 18.2197 22.3086 18.4824 22.4707C17.6895 22.5586 16.3652 22.5781 15.46 21.8613ZM16.4502 15.4805C16.4502 15.3105 16.5859 15.1758 16.7568 15.1758C16.7949 15.1758 16.8301 15.1836 16.8613 15.1953C16.9033 15.2109 16.9424 15.2344 16.9727 15.2695C17.0273 15.3223 17.0586 15.4004 17.0586 15.4805C17.0586 15.6504 16.9229 15.7852 16.7529 15.7852C16.582 15.7852 16.4502 15.6504 16.4502 15.4805ZM19.5273 17.0625C19.3301 17.1426 19.1328 17.2129 18.9434 17.2207C18.6494 17.2344 18.3281 17.1152 18.1533 16.9688C17.8828 16.7422 17.6895 16.6152 17.6074 16.2168C17.5732 16.0469 17.5928 15.7852 17.623 15.6348C17.6934 15.3105 17.6152 15.1035 17.3877 14.9141C17.2012 14.7598 16.9658 14.7188 16.7061 14.7188C16.6094 14.7188 16.5205 14.6758 16.4541 14.6406C16.3457 14.5859 16.2568 14.4512 16.3418 14.2852C16.3691 14.2324 16.501 14.1016 16.5322 14.0781C16.8838 13.877 17.29 13.9434 17.666 14.0938C18.0146 14.2363 18.2773 14.498 18.6562 14.8672C19.0439 15.3145 19.1133 15.4395 19.334 15.7734C19.5078 16.0371 19.667 16.3066 19.7754 16.6152C19.8408 16.8066 19.7559 16.9648 19.5273 17.0625Z"
                              fill-rule="nonzero" fill="#4D6BFE"></path>
                          </svg>
                        </span>
                      </div>
                    </template>
                  </el-popover>
                  <template v-else>
                    <span class="age">{{ cell.age }}</span>
                    <span class="stage">{{ cell.stage }}</span>
                  </template>
                </div>
              </div>
            </el-card>
          </div>
        </div>
      </div>
      <!-- 说明界面 -->
      <Instructions v-else-if="currentView === 'instructions'" @back="showMainView" @toggle-sidebar="handleCollapse"
        :isCollapse="isCollapse" :isDark="isDark" :isMobile="isMobile" :toggleDark="toggleDark"
        :followSystem="followSystem" :toggleFollowSystem="toggleFollowSystem" :isFullscreen="isFullscreen"
        :toggleFullScreen="toggleFullScreen" />
      <footer class="app-footer">
        <div class="footer-content">
          <div class="footer-logo">
            <span class="logo-text">人生计算器</span>
            <span class="version-badge">{{ appVersion }}</span>
          </div>
          <div class="footer-links lianxi-icon">
            <a href="https://gitee.com/jiqingzhe/life-calc" target="_blank" rel="noopener noreferrer">
              <AiOutlineFork size="20" />Gitee
            </a>
            <!--GitHub项目连接-->
            <a href="https://github.com/JiQingzhe2004/Life-Calculator" target="_blank" rel="noopener noreferrer">
                <AiFillGithub />GitHub
            </a>
            <span class="divider">|</span>
            <a href="https://www.douyin.com/user/MS4wLjABAAAAnB8dkCUz4n75aT3gTPyPXWHLLI93elB4PRQjCLgiE3QJES43z76OernKbls95D4c?from_tab_name=main" target="_blank" rel="noopener noreferrer">
              <AiFillTikTok />抖音
            </a>
            <a href="https://www.zhihu.com/people/aiqji" target="_blank" rel="noopener noreferrer">
              <AiFillZhihuCircle />知乎
            </a>
            <span class="divider">|</span>
            <a href="#" @click.prevent="showInstructions">
              <AiOutlineExclamationCircle />使用说明
            </a>
          </div>
          <div class="footer-links" >
            <DiNodejs />
            <DiNpm />
            <DiGit />
            <DiGitBranch />
            <DiJavascript1 />
            <DiMarkdown />
            <AiFillAppstore />
            <AiOutlineLaptop />
          </div>
          <div class="footer-motto">每一刻都值得铭记，每一秒都充满可能</div>
          <div class="copyright-text">
            © {{ new Date().getFullYear() }} 人生计算器 · 探索你的人生轨迹 · 作者：吉庆喆
          </div>
        </div>
      </footer>
    </div>
  </div>
</template>

<style scoped>

/* 在App.vue的style标签中添加 */
.lianxi-icon svg {
  width: 16px !important; 
  height: 16px !important;
}
/* Logo样式 */
.header-logo {
  width: 28px;
  height: 28px;
  margin-right: 10px;
  vertical-align: middle;
  filter: brightness(1.2);
  transition: all 0.3s ease;
  animation: pulse 2s infinite ease-in-out;
}

.clickable-title:hover .header-logo {
  transform: rotate(15deg);
}

/* 添加轻微的脉动动画 */
@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

/* 暗黑模式下的logo样式 */
.dark .header-logo {
  filter: brightness(1.5);
}

/* 移动端适配 */
@media screen and (max-width: 768px) {
  .header-logo {
    width: 24px;
    height: 24px;
    margin-right: 8px;
  }
}

/* Logo样式 */
.loding-logo {
  width: 60px;
  height: 60px;
  vertical-align: middle;
  filter: brightness(1.2);
  transition: all 0.3s ease;
  animation: pulse 2s infinite ease-in-out;
  border-radius: 20%;
}

.clickable-title:hover .loding-logo {
  transform: rotate(16deg);
}

/* 添加轻微的脉动动画 */
@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

/* 暗黑模式下的logo样式 */
.dark .loding-logo {
  filter: brightness(1.5);
}

/* 移动端适配 */
@media screen and (max-width: 768px) {
  .loding-logo {
    width: 60px;
    height: 60px;
  }
}
/* 替换原有的card-image样式 */
.image-container {
  position: relative;
  width: 100%;
  margin: 0 auto 20px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
  transition: all 0.4s ease;
  cursor: pointer;
}
.image-container:hover {
  transform: translateY(-5px) scale(1.01);
  box-shadow: 0 12px 30px rgba(56, 123, 255, 0.25);
}
.card-image {
  display: block;
  width: 100%;
  height: auto;
  transition: all 0.5s ease;
  filter: brightness(1);
}
.image-container:hover .card-image {
  filter: brightness(1.1);
}
.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(56, 123, 255, 0.5));
  opacity: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.4s ease;
}
.image-container:hover .image-overlay {
  opacity: 1;
}
.overlay-content {
  color: #fff;
  text-align: center;
  transform: translateY(20px);
  transition: all 0.4s ease;
}
.image-container:hover .overlay-content {
  transform: translateY(0);
}
.overlay-content span {
  display: block;
  margin-top: 10px;
  font-size: 18px;
  font-weight: bold;
  text-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
/* 暗黑模式适配 */
.dark .image-container {
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
.dark .image-container:hover {
  box-shadow: 0 12px 30px rgba(126, 185, 255, 0.25);
}
/* 为移动端优化 */
@media screen and (max-width: 768px) {
  .image-container {
    margin-bottom: 15px;
    border-radius: 8px;
  }
  .overlay-content span {
    font-size: 16px;
  }
}
/* 添加系统主题按钮样式 */
.system-theme-btn {
  border: 1px solid var(--el-border-color);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
  outline: none;
}

.system-theme-btn:hover {
  transform: rotate(15deg);
}

/* 全屏按钮样式 */
.fullscreen-btn {
  border: 1px solid var(--el-border-color);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.fullscreen-btn:hover {
  transform: scale(1.08);
}

.fullscreen-btn.is-active {
  background-color: var(--el-color-primary);
  color: white;
  border-color: var(--el-color-primary);
}

/* 调整按钮组间距 */
.header-buttons {
  display: flex;
  gap: 8px;
  align-items: center;
}

@media screen and (max-width: 768px) {
  .header-buttons {
    gap: 4px;
  }
}

/* 全屏按钮样式 */
.fullscreen-btn {
  border: 1px solid var(--el-border-color);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.fullscreen-btn:hover {
  transform: scale(1.08);
}

.fullscreen-btn.is-active {
  background-color: var(--el-color-primary);
  color: white;
  border-color: var(--el-color-primary);
}

.version-container {
  position: absolute;
  bottom: 20px;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
  gap: 5px;
}

.sidebar.collapsed .version-container {
  justify-content: center;
}

.version-text {
  opacity: 0.8;
  transition: opacity 0.3s;
}

.version-container:hover .version-text {
  opacity: 1;
}

/* 确保侧边栏底部有足够空间 */
.sidebar {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1000;
  transition: all 0.5s;
  border-right: 1px solid var(--el-border-color-light);
  background-color: var(--el-bg-color);
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding-bottom: 60px;
  /* 为版本号预留空间 */
  box-sizing: border-box;
}

/* 添加系统主题按钮样式 */
.system-theme-btn {
  border: 1px solid var(--el-border-color);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
  outline: none;
}

.system-theme-btn:hover {
  transform: rotate(15deg);
}

/* 加载屏幕样式 */
.loading-screen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #887fffbe;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.dark .loading-screen {
  background-color: #0e1523c3;
}

.loading-content {
  text-align: center;
  color: #ffffff;
}

.loading-spinner {
  margin-bottom: 20px;
}

.loading-title {
  font-size: 28px;
  margin: 10px 0;
  font-weight: 600;
}

.loading-subtitle {
  font-size: 16px;
  opacity: 0.8;
}

/* 加载动画 */
@keyframes rotate {
  100% {
    transform: rotate(360deg);
  }
}

/* 淡入淡出过渡 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

@keyframes dash {
  0% {
    stroke-dashoffset: 128;
  }

  50% {
    stroke-dashoffset: 32;
  }

  100% {
    stroke-dashoffset: 128;
  }
}
/* 在<style scoped>中添加或修改 */
.title-container {
  display: flex;
  align-items: center;
  gap: 10px;
}

.title-text {
  cursor: pointer;
  user-select: none;
  transition: opacity 0.2s;
}

.title-text:active {
  opacity: 0.7;
}

.icon-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px;
  cursor: pointer;
  border-radius: 50%;
  transition: background-color 0.2s;
}

.icon-wrapper:active {
  background-color: rgba(255, 255, 255, 0.2);
}

/* 思维链按钮过渡效果 */
.show-reasoning-btn {
  transition: all 0.3s ease;
}

.show-reasoning-btn:active {
  transform: scale(0.95);
}

/* 思维链按钮图标旋转效果 */
.show-reasoning-btn .el-icon {
  transition: transform 0.3s ease;
}

.show-reasoning-btn:not(.is-disabled):hover .el-icon {
  transform: translateY(-2px);
}

/* 思维链显示/隐藏动画 */
.reasoning-enter-active,
.reasoning-leave-active {
  transition: all 0.5s ease;
  max-height: 2000px;
  /* 足够大的高度以确保能显示完整内容 */
  opacity: 1;
  overflow: hidden;
}

.reasoning-enter-from,
.reasoning-leave-to {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  padding-top: 0;
  padding-bottom: 0;
}

/* 优化思维链标题的动画效果 */
.reasoning-content .reasoning-header {
  transition: opacity 0.3s ease;
}

.reasoning-enter-from .reasoning-header,
.reasoning-leave-to .reasoning-header {
  opacity: 0;
}

/* 优化思维链内容的动画效果 */
.reasoning-content pre {
  transition: opacity 0.4s ease 0.1s;
}

.reasoning-enter-from pre,
.reasoning-leave-to pre {
  opacity: 0;
}

:deep(.export-dialog .el-dialog) {
  background-color: rgba(255, 255, 255, 0.61);
  /* 亮色模式下的半透明背景 */
  backdrop-filter: blur(10px);
  /* 添加模糊效果，增强视觉体验 */
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  /* 更加柔和的阴影 */
  border: 1px solid rgba(255, 255, 255, 0.18);
  /* 微妙的边框 */
}

/* 暗黑模式下的半透明效果 */
.dark :deep(.export-dialog .el-dialog) {
  background-color: rgba(36, 53, 78, 0.85);
  /* 暗色模式下的半透明背景 */
  backdrop-filter: blur(10px);
  border: 1px solid rgba(52, 67, 88, 0.3);
}

/* 确保对话框内容清晰可见 */
.export-dialog-content {
  padding: 20px 0;
}

.export-dialog-content p {
  margin-bottom: 20px;
  font-size: 16px;
  color: var(--el-text-color-primary);
}

/* 改进按钮样式 */
.export-dialog .dialog-footer {
  display: flex;
  justify-content: center;
  gap: 20px;
  padding-top: 10px;
}

.export-dialog .dialog-footer .el-button {
  height: 40px;
  min-width: 100px;
}

/* 添加思维链相关样式 */
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.reasoning-content {
  margin-top: 20px;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 8px;
  border-left: 4px solid #409eff;
  font-size: 0.9em;
}

.reasoning-content pre {
  white-space: pre-wrap;
  font-family: "Courier New", Courier, monospace;
  color: #606266;
  line-height: 1.5;
  overflow-x: auto;
  margin: 0;
}

.reasoning-header {
  margin-bottom: 10px;
}

/* 夜间模式适配 */
.dark .reasoning-content {
  background-color: #283347;
  border-left: 4px solid #7eb9ff;
}

.dark .reasoning-content pre {
  color: #c0c4cc;
}

.clickable-title {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.clickable-title:active {
  opacity: 0.8;
}

.title-icon {
  font-size: 0.8em;
  margin-left: 5px;
}

/* 为进度条添加呼吸动画效果 */
.chart-container :deep(.el-progress-bar__outer) {
  border-radius: 8px;
  overflow: hidden;
}

.chart-container :deep(.el-progress-bar__inner) {
  position: relative;
  border-radius: 8px;
  transition: width 0.5s ease;
}

.chart-container :deep(.el-progress-bar__inner)::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(90deg,
      rgba(255, 255, 255, 0) 0%,
      rgba(255, 255, 255, 0.2) 50%,
      rgba(255, 255, 255, 0) 100%);
  animation: progress-shine 2s infinite;
  border-radius: inherit;
}

@supports (-webkit-touch-callout: none) {

  /* 专门针对iOS设备的样式 */
  input,
  textarea,
  select,
  .el-input__inner {
    font-size: 16px !important;
  }
}

@keyframes progress-shine {
  0% {
    transform: translateX(-100%);
  }

  100% {
    transform: translateX(200%);
  }
}

/* 夜间模式进度条调整 */
.dark .chart-container :deep(.el-progress-bar__inner)::after {
  background: linear-gradient(90deg,
      rgba(0, 0, 0, 0) 0%,
      rgba(255, 255, 255, 0.1) 50%,
      rgba(0, 0, 0, 0) 100%);
}

/* 让进度条文字更明显 */
.chart-container :deep(.el-progress__text) {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 14px !important;
}

.dark .chart-container :deep(.el-progress__text) {
  color: #e0e0e0;
}

/* 秒数动画效果 */
.time-details-row:last-child .time-unit:last-child {
  animation: pulse-second 1s infinite;
  position: relative;
  overflow: hidden;
}

@keyframes pulse-second {
  0% {
    background-color: #f5f7fa;
  }

  50% {
    background-color: #ecf5ff;
  }

  100% {
    background-color: #f5f7fa;
  }
}

/* 为秒数添加动态效果 */
.time-details-row:last-child .time-unit:last-child::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background-color: #409eff;
  animation: second-progress 1s linear infinite;
  transform-origin: left center;
}

@keyframes second-progress {
  0% {
    transform: scaleX(0);
  }

  100% {
    transform: scaleX(1);
  }
}

/* 暗黑模式下的秒数动画 */
.dark .time-details-row:last-child .time-unit:last-child {
  animation: dark-pulse-second 1s infinite;
}

@keyframes dark-pulse-second {
  0% {
    background-color: #344358;
  }

  50% {
    background-color: #3a4b63;
  }

  100% {
    background-color: #344358;
  }
}

.dark .time-details-row:last-child .time-unit:last-child::after {
  background-color: #7eb9ff;
}

/* 为毫秒添加快速动画，增强时间流逝感 */
.time-details-total {
  position: relative;
}

.time-details-total::after {
  content: attr(data-milliseconds);
  position: absolute;
  font-size: 0.7em;
  opacity: 0.5;
  right: 30%;
  bottom: -2px;
  animation: fade 0.5s infinite alternate;
}

@keyframes fade {
  from {
    opacity: 0.3;
  }

  to {
    opacity: 0.6;
  }
}

.time-unit.millisecond {
  min-width: 40px;
  /* 毫秒需要更宽的显示区域 */
  background-color: #f0f9ff;
  font-variant-numeric: tabular-nums;
  /* 等宽字符，防止闪烁 */
  animation: millisecond-pulse 0.5s infinite alternate;
}

@keyframes millisecond-pulse {
  0% {
    background-color: #f0f9ff;
  }

  100% {
    background-color: #d9ecff;
  }
}

.dark .time-unit.millisecond {
  background-color: #304156;
  animation: dark-millisecond-pulse 0.5s infinite alternate;
}

@keyframes dark-millisecond-pulse {
  0% {
    background-color: #304156;
  }

  100% {
    background-color: #283446;
  }
}

/* 统计卡片夜间模式 */
.dark .stats-container .stat-item {
  background-color: #283347;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.dark .stat-value {
  color: #7eb9ff;
}

.dark .stat-label {
  color: #a0a0a0;
}

/* 图表容器夜间模式 */
.dark .chart-container {
  background-color: #283347;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.dark .chart-title {
  color: #e0e0e0;
}

.empty-state {
  padding: 30px 0;
  text-align: center;
}

.dark .empty-state {
  color: #a0a0a0;
}

.time-details-section {
  background-color: #ffffff;
  border-radius: 12px;
  padding: 15px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.time-details-title {
  font-size: 16px;
  font-weight: 600;
  color: #000000;
  margin-bottom: 15px;
  text-align: center;
}

.time-details-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.time-details-column {
  background-color: #ffffff;
  border-radius: 10px;
  padding: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.time-details-header {
  font-weight: 600;
  color: #409eff;
  text-align: center;
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 1px dashed #e8e8e8;
}

.time-details-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.time-details-row {
  display: flex;
  justify-content: center;
  gap: 8px;
  font-size: 0.95em;
  color: #606266;
}

.time-unit {
  display: inline-block;
  min-width: 24px;
  text-align: center;
  font-weight: 700;
  color: #303133;
  background-color: #f5f7fa;
  border-radius: 4px;
  padding: 0 4px;
}

.time-details-total {
  text-align: center;
  margin-top: 10px;
  font-size: 0.9em;
  color: #e6a23c;
  font-weight: 700;
}

@media screen and (max-width: 768px) {
  .time-details-container {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .time-details-row {
    font-size: 0.9em;
  }

  .time-unit {
    min-width: 20px;
  }
}

/* 暗黑模式适配 */
.dark .time-details-section {
  background-color: #1c2b41;
}

.dark .time-details-column {
  background-color: #283347;
}

.dark .time-unit {
  background-color: #344358;
  color: #e0e0e0;
}

.dark .time-details-header {
  color: #7eb9ff;
}

.dark .time-details-title {
  color: #ffffff;
}

.loading-indicator {
  display: inline-block;
  margin-left: 5px;
  animation: pulse-animation 1s infinite;
}

@keyframes pulse-animation {

  0%,
  100% {
    opacity: 0.5;
    transform: scale(1);
  }

  50% {
    opacity: 1;
    transform: scale(0.8);
  }
}

.app-container {
  display: flex;
  min-height: 100vh;
  background-color: var(--el-bg-color);
  color: var(--el-text-color-primary);
}

.sidebar {
  height: 100vh;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 1000;
  transition: all 0.5s;
  border-right: 1px solid var(--el-border-color-light);
  background-color: var(--el-bg-color);
}

.sidebar.collapsed {
  width: 64px;
}

.sidebar-header {
  padding: 12px;
  display: flex;
  justify-content: flex-end;
}

.main-wrapper {
  flex: 1;
  margin-left: 64px;
  padding: 80px 0px 0px;
  transition: margin-left 0.3s;
  width: calc(100% - 64px);
  box-sizing: border-box;
}

.main-wrapper.expanded {
  width: calc(100% - 200px);
}

@media screen and (max-width: 768px) {
  .sidebar {
    transform: translateX(-100%);
  }

  .sidebar:not(.collapsed) {
    transform: translateX(0);
    width: 200px;
  }

  .main-wrapper,
  .main-wrapper.expanded {
    margin-left: 0;
    width: 100%;
  }

  .header,
  .main-wrapper.expanded .header {
    left: 0;
  }
}

.header {
  position: fixed;
  top: 0;
  right: 0;
  left: 64px;
  background: #387bff;
  padding: 0 15px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--el-border-color-light);
  z-index: 1000;
  transition: left 0.3s;
}

.mobile-header {
  justify-content: space-between;
  width: 100%;
  padding: 0 10px;
}

.mobile-header h2 {
  margin: 0;
  text-align: center;
  font-size: 1.2rem;
}

.mobile-theme-toggle {
  display: flex;
  align-items: center;
}

.theme-toggle-btn {
  border: 1px solid var(--el-border-color);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.header-content {
  display: flex;
  align-items: center;
  gap: 20px;
  width: 50%;
}

.header-content h1 {
  margin: 0;
  font-size: 1rem;
}

.header-actions {
  display: flex;
}

.notice-container {
  flex: 1;
  max-width: 600px;
}

.quote-container {
  display: flex;
  align-items: center;
  gap: 8px;
  font-style: italic;
}

.quote {
  margin: 0;
  font-size: 0.9rem;
  color: #ffffff;
}

.quote-author {
  margin: 0;
  font-size: 0.8rem;
  color: #dcdfe6;
}

.dark .header {
  background: #0e1f3f;
}

.dark .quote,
.dark .quote-author {
  color: var(--el-text-color-primary);
}

.notice-container {
  margin: 15px auto;
  max-width: 800px;
}

.notice-container :deep(.el-alert) {
  background-color: rgba(255, 255, 255, 0.9);
  border: none;
}

.notice-container :deep(.el-alert__title) {
  font-size: 16px;
  color: #2c3e50;
}

.notice-container :deep(.el-alert__description) {
  font-size: 14px;
  color: #34495e;
  margin: 5px 0;
}

.header h1 {
  margin: 0;
  font-size: 3.5em;
  font-weight: 700;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
}

.quote-container {
  font-style: italic;
}

.quote {
  font-size: 1em;
  margin-bottom: 5px;
}

.quote-author {
  font-size: 0.9em;
  opacity: 0.8;
}

.main-content {
  display: grid;
  grid-template-columns: 350px 1fr;
  gap: 20px;
  padding: 20px;
}

@media screen and (max-width: 768px) {
  .header {
    height: 50px;
  }

  .header-content {
    width: 100%;
  }

  .main-content {
    grid-template-columns: 1fr;
    padding: 5px;
  }

  .header h1 {
    font-size: 2.5em;
  }

  .quote {
    font-size: 1em;
  }

  .stats-container {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }

  .stat-item {
    padding: 10px;
  }

  .stat-value {
    font-size: 1.5em;
  }

  .life-grid {
    grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
    gap: 8px;
  }

  .life-cell {
    font-size: 0.9em;
  }

  .stage-chart {
    height: 250px;
  }

  .el-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .el-form-item {
    margin-right: 0;
    width: 100%;
  }

  .el-date-picker,
  .el-input-number {
    width: 100%;
  }

  .description-content {
    font-size: 1em;
    line-height: 1.6;
    color: #474747;
  }

  .dark .description-content {
    color: #bbbbbb;
  }

  .milestones-card .el-timeline {
    padding-left: 16px;
  }

  .milestones-card .el-timeline-item__content {
    font-size: 0.9em;
  }
}

@media screen and (max-width: 480px) {
  .app-container {
    padding: 5px;
  }

  .header {
    padding: 0 10px;
    height: 50px;
    z-index: 2001;
  }

  .header h1 {
    font-size: 1.8em;
  }

  .stats-container {
    grid-template-columns: 1fr;
  }

  .life-grid {
    grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
    gap: 6px;
  }

  .stage-chart {
    height: 200px;
  }
}

.input-section {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.stats-container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 15px;
}

.stat-item {
  text-align: center;
  padding: 15px;
  border-radius: 12px;
  background-color: #ffffff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.stat-item:hover {
  transform: translateY(-5px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}

.stat-item .el-icon {
  font-size: 24px;
  margin-bottom: 5px;
}

.stat-item.primary .el-icon {
  color: #409eff;
}

.stat-item.success .el-icon {
  color: #67c23a;
}

.stat-item.warning .el-icon {
  color: #e6a23c;
}

.stat-item.info .el-icon {
  color: #909399;
}

.chart-container {
  padding: 15px;
  background-color: #ffffff;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.chart-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 15px;
}

.stage-chart {
  height: 300px;
  width: 100%;
}

.stat-value {
  font-size: 1.8em;
  font-weight: bold;
  color: #409eff;
}

.stat-label {
  font-size: 0.9em;
  color: #606266;
  margin-top: 5px;
}

.progress-section {
  margin-top: 10px;
}

.progress-label {
  margin-bottom: 8px;
  font-weight: 500;
}

.life-grid-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.life-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
  gap: 10px;
  margin: 10px 0;
}

.life-cell {
  aspect-ratio: 1;
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  padding: 5px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  transition: all 0.3s;
  background-color: #fff;
  color: #606266;
  touch-action: manipulation;
}

.life-cell:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

@media (hover: none) {
  .life-cell:hover {
    transform: none;
    box-shadow: none;
  }

  .life-cell:active {
    transform: scale(0.95);
    background-color: #f5f7fa;
  }

  .stat-item:hover {
    transform: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  }
}

.life-cell.past {
  background-color: #67c23a;
  color: #fff;
}

.life-cell.current {
  background-color: #409eff;
  color: #fff;
  animation: pulse 2s infinite;
}

.life-cell.selected {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.life-cell.milestone {
  border: 2px solid #e6a23c;
  position: relative;
}

.life-cell.milestone::after {
  content: "⭐";
  position: absolute;
  top: -8px;
  right: -8px;
  font-size: 16px;
  color: #e6a23c;
}

.age {
  font-size: 1.2em;
  font-weight: bold;
}

.stage {
  font-size: 0.8em;
  margin-top: 4px;
}

.description-section {
  margin-top: 20px;
}

.description-content {
  line-height: 1.8;
  color: #474747;
  font-size: 1.1em;
}

.dark .description-content {
  color: #bbbbbb;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.05);
  }

  100% {
    transform: scale(1);
  }
}

/* 禁止iOS中的长按选择文本 */
* {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* 允许输入字段的文本选择 */
input,
textarea {
  -webkit-user-select: text;
  user-select: text;
}

/* 修复触摸行为 */
.el-button,
.el-input,
.el-date-picker,
.el-input-number,
.life-cell,
.sidebar,
.collapse-btn,
.theme-toggle-btn {
  touch-action: manipulation;
  outline: none;
}

/* 输入框聚焦时的样式 */
.input-focus {
  /* 可以添加一些视觉反馈 */
  position: relative;
}

/* 确保input-number始终使用数字键盘 */
.el-input-number__decrease,
.el-input-number__increase {
  touch-action: manipulation;
}

.el-input-number input {
  font-size: 16px !important;
  /* 防止iOS缩放 */
}

/* 底部版权样式 */
.app-footer {
  padding: 20px 0;
  border-top: 1px solid var(--el-border-color-light);
  background-color: var(--el-bg-color-overlay);
}

.footer-content {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
}

.footer-logo {
  display: flex;
  align-items: center;
  gap: 10px;
}

.logo-text {
  font-size: 18px;
  font-weight: bold;
  color: var(--el-color-primary);
}

.version-badge {
  background-color: var(--el-color-primary-light-8);
  color: var(--el-color-primary-dark-2);
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 10px;
  font-weight: bold;
}

.footer-links {
  display: flex;
  gap: 15px;
  align-items: center;
  margin: 5px 0;
}

.footer-links a {
  color: var(--el-text-color-regular);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 5px;
  transition: color 0.3s;
}

.footer-links a:hover {
  color: var(--el-color-primary);
}

.footer-links .divider {
  color: var(--el-border-color);
}

.copyright-text {
  color: var(--el-text-color-secondary);
  font-size: 14px;
}

.footer-motto {
  font-size: 13px;
  font-style: italic;
  color: var(--el-text-color-placeholder);
  margin-top: 5px;
}

/* 暗黑模式适配 */
.dark .app-footer {
  border-top-color: var(--el-border-color-darker);
  background-color: var(--el-bg-color);
}

.dark .version-badge {
  background-color: var(--el-color-primary-light-3);
  color: white;
}

/* 移动端适配 */
@media screen and (max-width: 768px) {
  .app-footer {
    margin-top: 10px;
    padding: 15px 0;
  }

  .footer-content {
    gap: 8px;
  }

  .footer-links {
    flex-wrap: wrap;
    justify-content: center;
    /* 大小小一点 */
    font-size: 10px;
  }

  .linnks-icon {
    font-size: 5px;
  }

  .logo-text {
    font-size: 16px;
  }

  .copyright-text {
    font-size: 12px;
  }

  .footer-motto {
    font-size: 11px;
  }
}
</style>